package com.stedu.mall.orderservice.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.stedu.mall.common.bean.*;
import com.stedu.mall.common.exception.SteduException;
import com.stedu.mall.common.service.AddrService;
import com.stedu.mall.common.service.GoodsService;
import com.stedu.mall.common.service.OrderService;
import com.stedu.mall.common.service.UserService;
import com.stedu.mall.orderservice.mapper.CartMapper;
import com.stedu.mall.orderservice.mapper.OrderDetailMapper;
import com.stedu.mall.orderservice.mapper.OrderServiceMapper;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

@DubboService
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderServiceMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CartMapper cartMapper;
    @DubboReference
    private UserService userService;
    @DubboReference
    private AddrService addrService;
    @DubboReference
    private GoodsService goodsService;

    @GlobalTransactional
    @Override
    public void insert(OrderVo orderVo) throws SteduException {
        /**
         * 1. 生成订单
         *     1) 生成订单Id - 雪花算法生成
         *     2) 获取地址对象 *
         *     3) 设置地址详情
         *     4) 添加订单
         * 2. 生成详情
         *     1) 获取购物车 - 判断购物车是否合法
         *     2) 获取商品信息 *
         *          是否存在
         *          是否下架
         *          库存是否充足
         *     3) 减去商品库存
         *     4) 添加详情
         * 3. 删除购物车
         */
        //创建订单对象
        Order order = new Order();
        //生成订单Id - 雪花算法生成
        String orderId = IdUtil.getSnowflakeNextIdStr();
        //设置订单id
        order.setId(orderId);

        //获取地址对象
        Addr addr = addrService.selectById(orderVo.getAddrId());
        //设置地址详情
        order.setAddrDetail(addr.getContact() + " " +
                addr.getPhone() + " " +
                addr.getProvince() +
                addr.getCity() +
                addr.getDistrict() +
                addr.getStreet() +
                addr.getAddress());
        //添加订单
        order.setUserId(orderVo.getUserId());
        order.setPayType(0);
        order.setAddrId(orderVo.getAddrId());
        order.setStatus(0);
        orderMapper.insert(order);

        //生成详情 - 每个购物车id对应一个商品详情
        for (Integer cartId : orderVo.getCartIds()) {
            //1) 获取购物车 - 判断购物车是否合法
            Cart cart = cartMapper.selectById(cartId);
            if (cart == null) {
                throw new SteduException("购物车不存在，无法生成订单");
            }

            if (!cart.getUserId().equals(orderVo.getUserId())) {
                throw new SteduException("购物车不合法，无法生成订单");
            }

            //2) 获取商品信息
            Goods goods = goodsService.selectById(cart.getGoodsId());
            //是否存在
            if (goods == null) {
                throw new SteduException("商品不存在，无法生成订单");
            }
            //是否下架 0下架 1下架
            if (goods.getStatus().equals(0)) {
                throw new SteduException("商品下架，无法生成订单");
            }
            //库存是否充足
            if (goods.getCount() < cart.getCount()) {
                throw new SteduException("商品库存不足，无法生成订单");
            }
            //3) 减去商品库存
            goods.setCount(goods.getCount() - cart.getCount());
            goodsService.update(goods);
            //4) 添加详情
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setCount(cart.getCount());
            orderDetail.setPrice(goods.getPrice());
            orderDetail.setOrderId(orderId);
            orderDetail.setGoodsId(goods.getId());
            orderDetailMapper.insert(orderDetail);
        }

        //删除购物车
        cartMapper.deleteByIds(Arrays.asList(orderVo.getCartIds()));
        orderVo.setOrderId(orderId);
    }
    @Override
    public boolean delete(String id) {
        return orderMapper.delete(id) == 1;
    }

    @Override
    public boolean update(Order order) {
        return orderMapper.update(order) == 1;
    }

    @Override
    public Order selectById(String id) {
        Order order = orderMapper.selectById(id);
        User user = userService.selectById(order.getUserId());
        order.setUser(user);
        List<OrderDetail> orderDetailList = order.getOrderDetailList();
        orderDetailList.stream()
                .forEach(orderDetail -> {
                    Goods goods = goodsService.selectById(orderDetail.getGoodsId());
                    orderDetail.setGoods(goods);
                });
        order.setOrderDetailList(orderDetailList);
        return order;
    }

    @Override
    public Order selectById1(String id, Integer userId) throws SteduException {
        //根据订单ID查询
        Order order = orderMapper.selectById(id);
        //判断订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new SteduException("订单不属于当前用户，无法支付");
        }
        //查询订单详情对应的商品信息
        for (OrderDetail orderDetail : order.getOrderDetailList()) {
            Goods goods = goodsService.selectById(orderDetail.getGoodsId());
            orderDetail.setGoods(goods);
        }
        return order;
    }

    @Override
    public PageInfo<Order> selectByUserId(Integer userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Order> orders = orderMapper.selectByUserId(userId);
        orders.stream()
                .forEach(order -> {
                    User user = userService.selectById(userId);
                    order.setUser(user);
                });
        PageInfo<Order> pageInfo = new PageInfo<>(orders);
        return pageInfo;
    }

    @Override
    public PageInfo<Order> selectAll(Order condition, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Order> orders = orderMapper.selectAll(condition);
        orders.stream()
                .forEach(order -> {
                    User user = userService.selectById(order.getUserId());
                    order.setUser(user);
                });
        PageInfo<Order> pageInfo = new PageInfo<>(orders);
        return pageInfo;
    }

    @GlobalTransactional
    @Override
    public void pay(OrderVo orderVo) throws SteduException {
        //根据orderId查询订单
        Order order = orderMapper.selectById(orderVo.getOrderId());
        //判断订单是否存在
        if (order == null) {
            throw new SteduException("订单不存在，无法支付");
        }
        if (!order.getUserId().equals(orderVo.getUserId())) {
            throw new SteduException("订单不属于该用户");
        }
        if (!order.getStatus().equals(0)) {
            throw new SteduException("");
        }
        order.setStatus(1);
        order.setPayType(0);
        orderMapper.update(order);

        User user = userService.selectById(orderVo.getUserId());
        String payPwdMySQL = user.getPayPassword();
        if (payPwdMySQL == null) {
            throw new SteduException("没有设置支付密码，请设置后下单");
        }
        //对用户支付密码加密
        String md5Pwd = SecureUtil.md5(SecureUtil.md5(orderVo.getPayPwd() + user.getSalt()));
        if (!md5Pwd.equals(payPwdMySQL)) {
            throw new SteduException("支付密码错误");
        }
        //计算当前订单的总金额
        BigDecimal sum = new BigDecimal("0");
        for (OrderDetail orderDetail : order.getOrderDetailList()) {
            BigDecimal count = new BigDecimal(orderDetail.getCount());
            BigDecimal price = orderDetail.getPrice();
            sum = sum.add(price.multiply(count));
        }
        //判断余额是否充足
        if (user.getMoney().compareTo(sum) < 0) {
            throw new SteduException("余额不足，无法支付");
        }
        //扣除金额update
        User u = new User();
        u.setId(user.getId());
        u.setMoney(user.getMoney().subtract(sum));

        userService.update(u);
    }
}
